#include "motorshow.h"

MotorShow::MotorShow(QMainWindow *parent) : QDialog(parent)
{
    renewable = true;
    clicked = false;
    Status = 0;
    this->setFixedSize(1200,800);
    this->setWindowTitle("电机监视器@Avengers");
    this->move(0,0);

    uartselect = new UartSelect();
    uartselect->move(parent->x()+200,parent->y()+200);
    uartselect->exec();

    int baud,check,data,stop;

    QString st = uartselect->selectedUartName;
    baud = uartselect->selectedBaud;
    check = uartselect->selectedCheck;
    data = uartselect->selectedData;
    stop = uartselect->selectedStop;

    delete uartselect;

    if (st=="NotSelected")
    {
        QMessageBox::information(NULL,"注意","未选择串口","确定");
        return;
    }
    Uart = new QSerialPort(st);
    if(!Uart->open(QIODevice::ReadOnly))
    {
        QMessageBox::warning(NULL,"错误","串口无法打开","确定");
        return;
    }
    const QSerialPort::BaudRate baudList[8] = {QSerialPort::Baud1200,QSerialPort::Baud2400,
                           QSerialPort::Baud4800,QSerialPort::Baud9600,
                           QSerialPort::Baud19200,QSerialPort::Baud38400,
                           QSerialPort::Baud57600,QSerialPort::Baud115200};
    Uart->setBaudRate(baudList[baud]);
    const QSerialPort::Parity checkList[5] = {QSerialPort::NoParity,QSerialPort::EvenParity,
                             QSerialPort::OddParity,QSerialPort::SpaceParity,
                             QSerialPort::MarkParity};
    Uart->setParity(checkList[check]);
    const QSerialPort::StopBits stopList[3]  ={QSerialPort::OneStop,QSerialPort::OneAndHalfStop,
                           QSerialPort::TwoStop};
    Uart->setStopBits(stopList[stop]);
    const QSerialPort::DataBits dataList[4] = {QSerialPort::Data5,QSerialPort::Data6,
                            QSerialPort::Data7,QSerialPort::Data8};
    Uart->setDataBits(dataList[data]);
    Uart->setFlowControl(QSerialPort::NoFlowControl);

    Uart->clearError();
    Uart->clear();
    connect(Uart,SIGNAL(readyRead()),this,SLOT(getData()));
    readable = false;
    count = 0;
    countl = 0;
    countr = 0;
    Status = 1;
    sum = 0;
    QString  leftLabel[11] = {"   0%PWM/   0","  20%PWM/  60","  40%PWM/ 120","  60%PWM/ 180"
                              ,"  80%PWM/ 240"," 100%PWM/ 300"," -20%PWM/---",
                              " -40%PWM/---"," -60%PWM/---"," -80%PWM/---",
                              "-100%PWM/---"};
    int position[11] = {300,240,180,120,60,0,360,420,480,540,600};
    for (int i=0;i<11;i++)
    {
        numberLabels[i] = new QLabel(this);
        numberLabels[i]->setText(leftLabel[i]);
        numberLabels[i]->move(0,position[i]);
    }
    numberLabels[10]->setVisible(false);
    //暂停键

    stopButton = new QPushButton(this);
    stopButton->setText("暂停");
    connect(stopButton,SIGNAL(clicked(bool)),this,SLOT(renewPause()));
    stopButton->resize(100,30);
    stopButton->move(0,620);
    //显示信息的label
    detailLabel = new QLabel(this);
    detailLabel->setVisible(false);

    QPalette *tracePalette = new QPalette();
    tracePalette->setColor(QPalette::Window,QColor(240,233,187));
    detailLabel->setPalette(*tracePalette);
    detailLabel->setAutoFillBackground(true);
    detailLabel->setAlignment(Qt::AlignCenter);
    detailLabel->setText("1");
    detailLabel->resize(200,200);
    //图例
    QLabel *sampleMap;
    sampleMap = new QLabel(this);
    sampleMap->resize(250,150);
    sampleMap->setText("红：目标速度\n蓝：当前速度\n绿：pwm输出");
    sampleMap->move(500,620);
    //两个移动按钮
    leftMoveButton = new QPushButton(this);
    leftMoveButton->setText("左移一秒");
    connect(leftMoveButton,SIGNAL(clicked(bool)),this,SLOT(leftMove()));
    leftMoveButton->resize(100,30);
    leftMoveButton->move(100,620);

    rightMoveButton = new QPushButton(this);
    rightMoveButton->setText("右移一秒");
    connect(rightMoveButton,SIGNAL(clicked(bool)),this,SLOT(rightMove()));
    rightMoveButton->resize(100,30);
    rightMoveButton->move(200,620);
    total = 0;
    leftMoveButton->setEnabled(false);
    rightMoveButton->setEnabled(false);
    delta = 0;
}
MotorShow::~MotorShow()
{
    if (Status==1)
        Uart->close();
}

void MotorShow::getData()
{
    Data = Uart->readAll();
    if (!(renewable&&!clicked))
        return;
    //目标转速 0-300
    //当前转速 0-300
    //当前pwm 0-1000
    for (int i=0;i<Data.length();i++)
    {
        if (readable)
        {
            count++;
            datas[count] = (unsigned char)Data[i];
            if (count==6)
            {
                count = 0;
                readable = false;
                renew();
                continue;
            }

        }
        if ((unsigned char)Data[i]==0xaa)
        {
            countl++;
            if (countl==2)
            {
                readable = true;
                countl = 0;
            }
        }
        else
            countl = 0;
    }
}
void MotorShow::renew()
{
    delta = 0;
    sum = (sum+1)%4000;
    if (total<4000)
    total++;
    else
        total=4000;
    targetData[sum] = datas[1]*0x0100+datas[2];
    speedData[sum] = datas[3]*0x0100+datas[4];
    pwmData[sum] = datas[5]*0x0100+datas[6];
    if (pwmData[sum]>0x1000)
    {
        datas[5] = ~(datas[5]);
        datas[6] = ~(datas[6]);
        datas[6]++;
        pwmData[sum] = -(datas[5]*0x100+datas[6]);
    }
    this->repaint();
}
void MotorShow::paintEvent(QPaintEvent *event)
{
    QPainter p(this);
    QPen pen(Qt::black,1);
    //QPen pen2(Qt::black,1);
    float tPix;
    tPix = 2;// 未考虑缩放
    QPen ptarget(Qt::red,3);
    QPen pspeed(Qt::blue,3);
    QPen ppwm(Qt::green,3);
    double  lastX_target = 0,lastY_target = 300,
            lastX_speed = 0,lastY_speed = 300,
            lastX_pwm = 0,lastY_pwm = 300;
    p.setPen(pen);
    for (int i=0;i<=10;i++)
        p.drawLine(QPoint(0,60*i),QPoint(1200,60*i));
    for (int i=0;i<=20;i++)
    {
        p.drawLine(QPoint(60*i,600),QPoint(60*i,0));
        if (i==20||i==10)
            p.drawText(QPointF(60*i-15,617),QString::number(((i-20+delta*20)*0.1))+".0");
        else
            p.drawText(QPointF(60*i-15,617),QString::number(((i-20+delta*20)*0.1)));

    }

    int k = 0;
    int t;
    for (int i = sum-399;i<=sum;i++)
    {
        t = i+delta*200;
        if (t<0)
            t = t+4000;
        p.setPen(ptarget);
        p.drawPoint(3*k,300-targetData[t]);
        p.drawLine(QPoint(lastX_target,lastY_target),QPoint(3*k,300-targetData[t]));
        lastX_target = 3*k;
        lastY_target = 300-targetData[t];

        p.setPen(pspeed);
        p.drawPoint(3*k,300-speedData[t]);
        p.drawLine(QPoint(3*k,300-speedData[t]),QPoint(lastX_speed,lastY_speed));
        lastX_speed = 3*k;
        lastY_speed = 300-speedData[t];

        p.setPen(ppwm);
        p.drawPoint(3*k,300-3*pwmData[t]/10.0);
        p.drawLine(QPoint(lastX_pwm,lastY_pwm),QPoint(3*k,300-3*pwmData[t]/10.0));
        lastX_pwm = 3*k;
        lastY_pwm = 300-3*pwmData[t]/10.0;
        k++;
    }

}
void MotorShow::mouseMoveEvent(QMouseEvent *e)
{
    detailLabel->move(max(e->x()-200,0),max(e->y()-200,0));
    detailLabel->setText("提前："+QString::number((1200-e->x())/3)+"场\n"+
                         "目标速度:"+QString::number(targetData[(sum-(1200-e->x())/3+400)%400])+
                         "\n当前速度:"+QString::number(speedData[(sum-(1200-e->x())/3+400)%400])+
                         "\npwm输出:"+QString::number(pwmData[(sum-(1200-e->x())/3+400)%400])
                            );

}
void MotorShow::mousePressEvent(QMouseEvent *e)
{
    clicked = true;
    renewPause();
    detailLabel->move(max(e->x()-200,0),max(e->y()-200,0));
    detailLabel->setText("提前："+QString::number((1200-e->x())/3)+"场\n"+
                         "目标速度:"+QString::number(targetData[(sum-(1200-e->x())/3+400)%400])+
                         "\n当前速度:"+QString::number(speedData[(sum-(1200-e->x())/3+400)%400])+
                         "\npwm输出:"+QString::number(pwmData[(sum-(1200-e->x())/3+400)%400])
                            );
    detailLabel->setVisible(true);
}

void MotorShow::mouseReleaseEvent(QMouseEvent *e)
{
    clicked = false;
    detailLabel->setVisible(false);
    //renewable = true;
}
void MotorShow::leftMove()
{
    if (delta==-18)
    {
        QMessageBox::warning(this,"注意","已经到达最左端。\n\n由于规模限制只能显示前20秒的图像。","确定");
        return;
    }
    if (-delta>((total-400)/200))
    {
        QMessageBox::warning(this,"注意","已经达到最左端。\n\n没有足够的数据。","确定");
        return;
    }

    delta --;
    repaint();

}

void MotorShow::rightMove()
{
    if (delta==1)
    {
        QMessageBox::warning(this,"错误","已到最右端","确定");
        return;
    }
    delta++;
    repaint();

}
